模型(Model)、观察(View)和投影(Projection)详解 您所在的位置:网站首页 prediction projection 区别 模型(Model)、观察(View)和投影(Projection)详解

模型(Model)、观察(View)和投影(Projection)详解

2024-06-29 06:39| 来源: 网络整理| 查看: 265

 

模型(Model)、观察(View)和投影(Projection)矩阵

在接下来的课程中,我们假定您已知如何绘制Blender经典模型小猴Suzanne。

利用模型、观察和投影矩阵,可以将变换过程清晰地分解为三个阶段。虽然此法并非必需(前两课我们就没用这个方法嘛),但采用此法较为稳妥。我们将看到,这种公认的方法对变换流程作了清晰的划分。

模型矩阵

这个三维模型和可爱的红色三角形一样,由一组顶点定义。顶点的XYZ坐标是相对于物体中心定义的:也就是说,若某顶点位于(0,0,0),则其位于物体的中心。

观察矩阵

这里再引用一下《飞出个未来》:

*引擎推动的不是飞船而是宇宙。飞船压根就没动过。*

 

好在用一个4x4矩阵就能表示这个投影¹ :

// Generates a really hard-to-read matrix, but a normal, standard 4x4 matrix nonetheless glm::mat4 projectionMatrix = glm::perspective( glm::radians(FoV), // The vertical Field of View, in radians: the amount of "zoom". Think "camera lens". Usually between 90° (extra wide) and 30° (quite zoomed in) 4.0f / 3.0f, // Aspect Ratio. Depends on the size of your window. Notice that 4/3 == 800/600 == 1280/960, sounds familiar ? 0.1f, // Near clipping plane. Keep as big as possible, or you'll get precision issues. 100.0f // Far clipping plane. Keep as little as possible. );

最后一个变换:

从摄像机空间(顶点都相对于摄像机定义)到齐次坐空间(Homogeneous Space)(顶点都在一个小立方体中定义。立方体内的物体都会在屏幕上显示)的变换。

最后一幅图示:

MVP.png转存失败重新上传取消

再添几张图,以便大家更好地理解投影变换。投影前,蓝色物体都位于摄像机空间中,红色的东西是摄像机的平截头体(frustum):这是摄像机实际能看见的区域。

用投影矩阵去乘前面的结果,得到如下效果:

此图中,平截头体变成了一个正方体(每条棱的范围都是-1到1,图不太明显),所有的蓝色物体都经过了相同的变形。因此,离摄像机近的物体就显得大一些,远的显得小一些。这和现实生活一样!

让我们从平截头体的”后面”看看它们的模样:

这就是您得到的图像!看上去太方方正正了,因此,还需要做一次数学变换使之适合实际的窗口大小。

这就是实际渲染的图像啦!

复合变换:模型观察投影矩阵(MVP)

再来一连串深爱已久的标准矩阵乘法:

// C++ : compute the matrix glm::mat4 MVPmatrix = projection * view * model; // Remember : inverted ! // GLSL : apply it transformed_vertex = MVP * in_vertex; 总结 第一步:创建模型观察投影(MVP)矩阵。任何要渲染的模型都要做这一步。 // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit 100 units glm::mat4 Projection = glm::perspective(glm::radians(45.0f), (float) width / (float)height, 0.1f, 100.0f); // Or, for an ortho camera : //glm::mat4 Projection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,0.0f,100.0f); // In world coordinates // Camera matrix glm::mat4 View = glm::lookAt( glm::vec3(4,3,3), // Camera is at (4,3,3), in World Space glm::vec3(0,0,0), // and looks at the origin glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down) ); // Model matrix : an identity matrix (model will be at the origin) glm::mat4 Model = glm::mat4(1.0f); // Our ModelViewProjection : multiplication of our 3 matrices glm::mat4 mvp = Projection * View * Model; // Remember, matrix multiplication is the other way around 第二步:把MVP传给GLSL // Get a handle for our "MVP" uniform // Only during the initialisation GLuint MatrixID = glGetUniformLocation(programID, "MVP"); // Send our transformation to the currently bound shader, in the "MVP" uniform // This is done in the main loop since each model will have a different MVP matrix (At least for the M part) glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]); 第三步:在GLSL中用MVP变换顶点 // Input vertex data, different for all executions of this shader. layout(location = 0) in vec3 vertexPosition_modelspace; // Values that stay constant for the whole mesh. uniform mat4 MVP; void main(){ // Output position of the vertex, in clip space : MVP * position gl_Position = MVP * vec4(vertexPosition_modelspace,1); }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有